package com.gzhryc.net_marketing.cloud.micro.api.controllers.cloud;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.api.DefaultAPICodeConstants;
import com.gzhryc.common.api.DefaultAPIResponse;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.net_marketing.api.protocol.account.*;
import com.gzhryc.net_marketing.cloud.account.dao.db.*;
import com.gzhryc.net_marketing.cloud.account.dao.enums.CloudPayAccountDepositOrderEnum;
import com.gzhryc.net_marketing.cloud.account.dao.enums.CloudPayAccountOperateRecordEnum;
import com.gzhryc.net_marketing.cloud.account.services.*;
import com.gzhryc.net_marketing.cloud.business.dao.db.MarketSupplier;
import com.gzhryc.net_marketing.cloud.business.services.MarketSupplierService;
import com.gzhryc.net_marketing.core.enums.CloudPayAccountEnum;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EPayState;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.net_marketing.cloud.account.dao.enums.CloudPayAccountExpenditureOrderEnum;
import com.gzhryc.weixin.gzh.WxAuthorityApi;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

public class CloudPayAccountHandleAPIController {

    static Logger log = Logger.getLogger(CloudPayAccountHandleAPIController.class);

    /**
     * 充值请求
     * @param request
     * @return
     */
    @Route(value = { "/market/cloud_api/v1/payAccount/recharge.do" })
    public CloudPayAccountRechargeResponse recharge(HttpServletRequest request){
        CloudPayAccountRechargeResponse apiResp = new CloudPayAccountRechargeResponse(DefaultAPICodeConstants.EXECUTE_ERROR,"处理失败");
        CloudPayAccountRechargeRequest apiReq = WebUtils.getJsonRequest(request,CloudPayAccountRechargeRequest.class);
        log.info("云账号充值请求：{{0:json}}",apiReq);
        if(apiReq != null && apiReq.getBody().getAccountId() != null
                && StringTools.isNotBlank(apiReq.getBody().getAccountToken())) {
            Integer payType = apiReq.getBody().getPayType() == null?EPayType.WXPay.index():apiReq.getBody().getPayType();
            CloudPayAccount cloudPayAccount = CloudPayAccountService.self()
                    .getJoinByVisitToken(apiReq.getBody().getAccountId(),apiReq.getBody().getAccountToken());

            if(cloudPayAccount == null){
                apiResp.setMsg("未找到云支付账号");
                return apiResp;
            }

            if(StringTools.isNotBlank(apiReq.getBody().getTradeNo())){
                CloudPayAccountDepositOrder order = CloudPayAccountDepositOrderService.self().getByTradeNo(apiReq.getBody().getTradeNo());
                if(order == null){
                    apiResp.setMsg("未找到充值订单");
                    return apiResp;
                }

                if(CloudPayAccountDepositOrderEnum.State.WaitPay.index().equals(order.getState())){
                    if(StringUtils.isNotBlank(order.getExternalContent()) && order.getPayDate() != null){
                        Long hour = DateTools.differenceHour(order.getPayDate(),new Date());
                        if(hour < 2){
                            apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                            apiResp.getBody().setPayType(order.getPayType());
                            apiResp.getBody().setMoney(order.getPayMoney());
                            apiResp.getBody().setQrcodeContent(order.getExternalContent());
                            return apiResp;
                        }else{
                            CloudPayAccountDepositOrderService.self().waitToClose(order.getTradeNo());
                            apiResp.setMsg("订单已过期，请重新创建");
                            return apiResp;
                        }
                    }else{
                        CloudPayAccountDepositOrderService.self().waitToClose(order.getTradeNo());
                        apiResp.setMsg("订单已过期，请重新创建");
                        return apiResp;
                    }
                }else {
                    apiResp.setMsg("订单" +order.getStateName()+ "，请重新创建");
                    return apiResp;
                }
            }else {
                if(apiReq.getBody().getMoney() == null || apiReq.getBody().getMoney() < 100){
                    apiResp.setMsg("至少充值1元");
                    return apiResp;
                }
                try {
                    CloudPayAccountDepositOrder order = CloudPayAccountDepositOrderService.self().getWaitPayOrder(cloudPayAccount.getId());
                    if(order != null){
                        if(order.getPayMoney() == apiReq.getBody().getMoney() && order.getPayType().equals(payType)){
                            if(StringUtils.isNotBlank(order.getExternalContent()) && order.getPayDate() != null){
                                Long hour = DateTools.differenceHour(order.getPayDate(),new Date());
                                if(hour < 2){
                                    apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                                    apiResp.getBody().setPayType(order.getPayType());
                                    apiResp.getBody().setMoney(order.getPayMoney());
                                    apiResp.getBody().setQrcodeContent(order.getExternalContent());
                                    return apiResp;
                                }else{
                                    CloudPayAccountDepositOrderService.self().waitToClose(order.getTradeNo());
                                }
                            }else{
                                CloudPayAccountDepositOrderService.self().waitToClose(order.getTradeNo());
                            }
                        }else {
                            apiResp.setMsg("存在未支付的订单，请优先处理");
                            return apiResp;
                        }
                    }

                    if(EPayType.WXPay.index().equals(payType)) {
                        order = CloudPayAccountDepositOrderService.self().createWXPayDepositOrder(cloudPayAccount, apiReq.getBody().getMoney());
                        if (order != null && StringTools.isNotBlank(order.getExternalContent())) {
                            apiResp.setCode(DefaultAPICodeConstants.SUCCESS, null);
                            apiResp.getBody().setTradeNo(order.getTradeNo());
                            apiResp.getBody().setPayType(EPayType.WXPay.index());
                            apiResp.getBody().setMoney(order.getPayMoney());
                            apiResp.getBody().setQrcodeContent(order.getExternalContent());
                            return apiResp;
                        }
                    }else if(EPayType.Alipay.index().equals(payType)){
                        order = CloudPayAccountDepositOrderService.self().createAlipayDepositOrder(cloudPayAccount, apiReq.getBody().getMoney());
                        if (order != null && StringTools.isNotBlank(order.getExternalContent())) {
                            apiResp.setCode(DefaultAPICodeConstants.SUCCESS, null);
                            apiResp.getBody().setTradeNo(order.getTradeNo());
                            apiResp.getBody().setPayType(EPayType.Alipay.index());
                            apiResp.getBody().setMoney(order.getPayMoney());
                            apiResp.getBody().setQrcodeContent(order.getExternalContent());
                            return apiResp;
                        }
                    }
                } catch (LogicException e) {
                    apiResp.setMsg(e.getMessage());
                }
            }
        }else{
            apiResp.setCode(DefaultAPICodeConstants.EXECUTE_ERROR,"参数错误");
        }
        return apiResp;
    }

    @Route(value = { "/market/cloud_api/v1/payAccount/recharge/cancel.do" })
    public DefaultAPIResponse cancelRecharge(HttpServletRequest request){
        DefaultAPIResponse apiResp = new DefaultAPIResponse(DefaultAPICodeConstants.EXECUTE_ERROR,"处理失败");
        CloudPayAccountRechargeCancelRequest apiReq = WebUtils.getJsonRequest(request,CloudPayAccountRechargeCancelRequest.class);
        log.info("云账号充值取消请求：{{0:json}}",apiReq);
        if(apiReq != null && apiReq.getBody().getAccountId() != null
                && StringTools.isNotBlank(apiReq.getBody().getAccountToken()) && StringTools.isNotBlank(apiReq.getBody().getTradeNo())) {
            CloudPayAccount cloudPayAccount = CloudPayAccountService.self()
                    .getJoinByVisitToken(apiReq.getBody().getAccountId(),apiReq.getBody().getAccountToken());

            if(cloudPayAccount == null){
                apiResp.setMsg("未找到云支付账号");
                return apiResp;
            }

            CloudPayAccountDepositOrder order = CloudPayAccountDepositOrderService.self().getByTradeNo(apiReq.getBody().getTradeNo());
            if(order == null){
                apiResp.setMsg("未找到充值订单");
                return apiResp;
            }

            if(CloudPayAccountDepositOrderEnum.State.WaitPay.index().equals(order.getState())){
                if(CloudPayAccountDepositOrderService.self().waitToClose(order.getTradeNo())) {
                    apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                    return apiResp;
                }
            }else {
                apiResp.setMsg("订单" +order.getStateName()+ "，无法取消");
                return apiResp;
            }
        }else{
            apiResp.setCode(DefaultAPICodeConstants.EXECUTE_ERROR,"参数错误");
        }
        return apiResp;
    }

    /**
     * 支付请求
     * @param request
     * @return
     */
    @Route(value = { "/market/cloud_api/v1/payAccount/pay.do" })
    public CloudPayAccountPayResponse pay(HttpServletRequest request){
        CloudPayAccountPayResponse apiResp = new CloudPayAccountPayResponse(DefaultAPICodeConstants.EXECUTE_ERROR,"处理失败");
        CloudPayAccountPayRequest apiReq = WebUtils.getJsonRequest(request,CloudPayAccountPayRequest.class);
        log.info("云账号支付请求：{{0:json}}",apiReq);
        if(apiReq != null && apiReq.getBody().getAccountId() != null && StringTools.isNotBlank(apiReq.getBody().getAccountToken())
            && apiReq.getBody().getBusinessType() != null && StringTools.isNotBlank(apiReq.getBody().getBusinessTradeNo())) {
            if(CloudPayAccountEnum.BusinessType.GoodsOrderPay.name().equals(apiReq.getBody().getBusinessType())){
                CloudPayAccount payerAccount = CloudPayAccountService.self()
                        .getByPayToken(apiReq.getBody().getAccountId(),apiReq.getBody().getAccountToken());
                if(payerAccount == null){
                    apiResp.setMsg("未找到支付者云支付账号");
                    return apiResp;
                }

                CloudPayAccountExpenditureOrder expenditureOrder = CloudPayAccountExpenditureOrderService.self().getByBusinessTradeNo(apiReq.getBody().getBusinessTradeNo());
                if(expenditureOrder != null){
                    if(CloudPayAccountExpenditureOrderEnum.State.WaitPay.index().equals(expenditureOrder.getState())){
                        try {
                            if(CloudPayAccountExpenditureOrderService.self().pay(expenditureOrder,payerAccount)){
                                apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                                apiResp.getBody().setTradeNo(expenditureOrder.getTradeNo());
                                apiResp.getBody().setPayResult(EPayState.Success.index());
                                apiResp.getBody().setBusinessType(expenditureOrder.getBusinessType());
                                apiResp.getBody().setBusinessTradeNo(expenditureOrder.getBusinessTradeNo());
                                apiResp.getBody().setPayMoney(expenditureOrder.getMoney());
                            }
                        } catch (LogicException e) {
                            apiResp.setMsg(e.getMessage());
                        }
                        return apiResp;
                    }else if(CloudPayAccountExpenditureOrderEnum.State.Paying.index().equals(expenditureOrder.getState())){
                        apiResp.setMsg("支付中...");
                        return apiResp;
                    }else if(CloudPayAccountExpenditureOrderEnum.State.Settlement.index().equals(expenditureOrder.getState())
                        || CloudPayAccountExpenditureOrderEnum.State.Finish.index().equals(expenditureOrder.getState())){
                        apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                        apiResp.getBody().setTradeNo(expenditureOrder.getTradeNo());
                        apiResp.getBody().setPayResult(EPayState.Success.index());
                        apiResp.getBody().setBusinessType(expenditureOrder.getBusinessType());
                        apiResp.getBody().setBusinessTradeNo(expenditureOrder.getBusinessTradeNo());
                        apiResp.getBody().setPayMoney(expenditureOrder.getMoney());
                        return apiResp;
                    }else {
                        apiResp.setMsg("支付已关闭");
                        return apiResp;
                    }
                }

                //商品订单支付
                if(apiReq.getBody().getSupplyId() == null){
                    apiResp.setMsg("未获取供货商信息");
                    return apiResp;
                }else {
                    MarketSupplier networkMarketApp = MarketSupplierService.self().getById(apiReq.getBody().getSupplyId());
                    if(networkMarketApp == null || networkMarketApp.getAccountId() == null){
                        apiResp.setMsg("未获取供货商信息");
                        return apiResp;
                    }

                    expenditureOrder = new CloudPayAccountExpenditureOrder();
                    expenditureOrder.setTitle(apiReq.getBody().getTitle());
                    expenditureOrder.setAccountId(payerAccount.getId());
                    expenditureOrder.setPayeeAccountId(networkMarketApp.getAccountId());
                    expenditureOrder.setBusinessType(apiReq.getBody().getBusinessType());
                    expenditureOrder.setBusinessTradeNo(apiReq.getBody().getBusinessTradeNo());
                    expenditureOrder.setMoney(apiReq.getBody().getPayMoney());
                    expenditureOrder.setExtContent(apiReq.getBody().getExtContent());

                    try {
                        if(CloudPayAccountExpenditureOrderService.self().createAndPay(expenditureOrder,payerAccount)){
                            apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                            apiResp.getBody().setTradeNo(expenditureOrder.getTradeNo());
                            apiResp.getBody().setPayResult(EPayState.Success.index());
                            apiResp.getBody().setBusinessType(expenditureOrder.getBusinessType());
                            apiResp.getBody().setBusinessTradeNo(expenditureOrder.getBusinessTradeNo());
                            apiResp.getBody().setPayMoney(expenditureOrder.getMoney());
                        }
                    } catch (LogicException e) {
                        apiResp.setMsg(e.getMessage());
                    }
                }

            }
        }else{
            apiResp.setCode(DefaultAPICodeConstants.EXECUTE_ERROR,"参数错误");
        }
        return apiResp;
    }

    @Route(value = { "/market/cloud_api/v1/payAccount/settlement.do" })
    public CloudPayAccountSettlementResponse settlement(HttpServletRequest request){
        CloudPayAccountSettlementResponse apiResp = new CloudPayAccountSettlementResponse(DefaultAPICodeConstants.EXECUTE_ERROR,"处理失败");
        CloudPayAccountSettlementRequest apiReq = WebUtils.getJsonRequest(request,CloudPayAccountSettlementRequest.class);
        log.info("云账号结算请求：{{0:json}}",apiReq);
        if(apiReq != null && apiReq.getBody().getAccountId() != null && StringTools.isNotBlank(apiReq.getBody().getAccountToken()) && apiReq.getBody().getSettlementType() != null
                && StringTools.isNotBlank(apiReq.getBody().getBusinessTradeNo()) && StringTools.isNotBlank(apiReq.getBody().getTradeNo())) {
            CloudPayAccount cloudPayAccount = CloudPayAccountService.self()
                    .getByPayToken(apiReq.getBody().getAccountId(),apiReq.getBody().getAccountToken());
            if(cloudPayAccount == null){
                apiResp.setMsg("未找到云支付账号");
                return apiResp;
            }

            CloudPayAccountExpenditureOrder expenditureOrder = CloudPayAccountExpenditureOrderService.self().getByTradeNo(apiReq.getBody().getTradeNo());
            if(expenditureOrder == null){
                apiResp.setMsg("未找到结算订单");
                return apiResp;
            }

            if(!CloudPayAccountExpenditureOrderEnum.State.Settlement.index().equals(expenditureOrder.getState())){
                apiResp.setMsg("订单状态不允许");
                return apiResp;
            }

            if(!expenditureOrder.getBusinessTradeNo().equals(apiReq.getBody().getBusinessTradeNo())){
                apiResp.setMsg("业务订单号不匹配");
                return apiResp;
            }

            if(CloudPayAccountEnum.SettlementType.PayeeRequest.index().equals(apiReq.getBody().getSettlementType())){
                if(!expenditureOrder.getPayeeAccountId().equals(cloudPayAccount.getId())){
                    apiResp.setMsg("收款账号不匹配");
                    return apiResp;
                }
                if(CloudPayAccountEnum.BusinessType.GoodsOrderPay.name().equals(expenditureOrder.getBusinessType())) {
                    //收款人请求结算必须是10天之后订单
                    Integer day = DateTools.differenceDay(expenditureOrder.getCreateDate(), new Date());
                    if (day < 10) {
                        apiResp.setMsg("请等待10天后进行结算");
                        return apiResp;
                    }
                }
            }

            String operatorName = cloudPayAccount.getId()+"云支付账号";
            String reason = apiReq.getBody().getNote();
            if(StringTools.isBlank(reason)) {
                if (CloudPayAccountEnum.SettlementType.PayeeRequest.index().equals(apiReq.getBody().getSettlementType())) {
                    reason = "收款人请求订单超时结算";
                }
            }
            try {
                if(CloudPayAccountExpenditureOrderService.self().settlement(expenditureOrder,
                        CloudPayAccountOperateRecordEnum.OperatorType.Client.index(),operatorName,reason)){
                    apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                    apiResp.getBody().setPayResult(EPayState.Success.index());
                    apiResp.getBody().setBusinessTradeNo(expenditureOrder.getBusinessTradeNo());
                    apiResp.getBody().setTradeNo(expenditureOrder.getTradeNo());
                }
            } catch (LogicException e) {
                apiResp.setMsg(e.getMessage());
            }
        }else{
            apiResp.setCode(DefaultAPICodeConstants.EXECUTE_ERROR,"参数错误");
        }
        return apiResp;
    }

    @Route(value = { "/market/cloud_api/v1/payAccount/withdraw.do" })
    public CloudPayAccountWithdrawResponse withdraw(HttpServletRequest request){
        CloudPayAccountWithdrawResponse apiResp = new CloudPayAccountWithdrawResponse(DefaultAPICodeConstants.EXECUTE_ERROR,"处理失败");
        CloudPayAccountWithdrawRequest apiReq = WebUtils.getJsonRequest(request,CloudPayAccountWithdrawRequest.class);
        log.info("云账号取款请求：{{0:json}}",apiReq);
        if(apiReq != null && apiReq.getBody().getAccountId() != null && StringTools.isNotBlank(apiReq.getBody().getAccountToken())
            && apiReq.getBody().getMoney() != null && apiReq.getBody().getReceivingType() != null
                && StringTools.isNotBlank(apiReq.getBody().getReceivingId())&& StringTools.isNotBlank(apiReq.getBody().getReceivingName())
                && StringTools.isNotBlank(apiReq.getBody().getReceivingPhone())) {

            CloudPayAccount payerAccount = CloudPayAccountService.self()
                    .getByPayToken(apiReq.getBody().getAccountId(),apiReq.getBody().getAccountToken());

            if(payerAccount == null){
                apiResp.setMsg("未找到支付者云支付账号");
                return apiResp;
            }

            if(StringTools.isBlank(payerAccount.getWxpayAppId())){
                apiResp.setMsg("云支付账号未开通取款服务");
                return apiResp;
            }

            //验证数据
            CloudPayAccountWithdrawPayee withdrawUser = CloudPayAccountWithdrawPayeeService.self().getByKeys(payerAccount.getId()
                    ,apiReq.getBody().getReceivingType(),payerAccount.getWxpayAppId(),apiReq.getBody().getReceivingId());
            if(withdrawUser == null){
                apiResp.setMsg("未找到取款人信息");
                return apiResp;
            }

            if(!withdrawUser.getName().equals(apiReq.getBody().getReceivingName()) || !withdrawUser.getPhone().equals(apiReq.getBody().getReceivingPhone())){
                apiResp.setMsg("取款人验证信息失败");
                return apiResp;
            }

            try {
                CloudPayAccountWithdrawOrder withdrawOrder = CloudPayAccountWithdrawOrderService.self()
                        .add(payerAccount,withdrawUser,apiReq.getBody().getMoney());
                if(withdrawOrder != null){
                    apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                    apiResp.getBody().setTradeNo(withdrawOrder.getTradeNo());
                    apiResp.getBody().setPayResult(EPayState.Success.index());
                }
            } catch (LogicException e) {
                apiResp.setMsg(e.getMessage());
            }
        }else{
            apiResp.setCode(DefaultAPICodeConstants.EXECUTE_ERROR,"参数错误");
        }
        return apiResp;
    }

    @Route(value = { "/market/cloud_api/v1/payAccount/withdraw/payee/add.do" })
    public CloudPayAccountWithdrawPayeeAddResponse addWithdrawPayeeList(HttpServletRequest request){
        CloudPayAccountWithdrawPayeeAddResponse apiResp = new CloudPayAccountWithdrawPayeeAddResponse(DefaultAPICodeConstants.EXECUTE_ERROR,"获取注册失败");
        CloudPayAccountWithdrawPayeeAddRequest apiReq = WebUtils.getJsonRequest(request,CloudPayAccountWithdrawPayeeAddRequest.class);
        log.info("云账号新增取款人信息请求：{{0:json}}",apiReq);
        if(apiReq != null && apiReq.getBody().getAccountId() != null && StringTools.isNotBlank(apiReq.getBody().getAccountToken())) {
            CloudPayAccount cloudPayAccount = CloudPayAccountService.self()
                    .getByPayToken(apiReq.getBody().getAccountId(), apiReq.getBody().getAccountToken());
            if (cloudPayAccount == null) {
                apiResp.setCode(DefaultAPICodeConstants.EXECUTE_ERROR, "未找到云支付账号");
                return apiResp;
            }

            if(StringTools.isBlank(cloudPayAccount.getWxpayAppId())){
                apiResp.setMsg("云支付账号未开通取款服务");
                return apiResp;
            }

            String url = WebUtils.setHttpDomain(request,"/account/wx/bind.html");
            String qrcode = WxAuthorityApi.getOAuthUrl2(cloudPayAccount.getWxpayAppId(),url,cloudPayAccount.getId().toString());
            if(StringTools.isNotBlank(qrcode)){
                apiResp.setCode(DefaultAPICodeConstants.SUCCESS,null);
                apiResp.getBody().setQrcodeContent(qrcode);
            }
        }

        return apiResp;
    }
}
